#include "MQTTClient.h"
#include "log/log.h"
#include "app_mqtt.h"
#include "string.h"

#define ADDRESS "ws://192.168.55.32:1883"
#define CLIENTID "b253ba38-daf6-4b37-984f-5d8fdc6a1cfa"
#define TOPIC_PULL "pull" // 订阅的主题
#define TOPIC_PUSH "push" // 发送消息的主题
#define QOS 1
#define TIMEOUT 10000L

//指向MQTT客户端的句柄
static MQTTClient client;
//指向MQTT客户端的连接选项                         宏定义，用于初始化其结构体成员
static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
//MQTT客户端和服务端之间传输数据的结构     宏定义，用于初始化其结构体成员
static MQTTClient_message pubmsg = MQTTClient_message_initializer;

static int (*recv_cb)(char* json) = NULL;
// 发送消息完成的回调函数
static void delivered(void *context, MQTTClient_deliveryToken dt)
{
    log_info("Message with token value %d delivery confirmed", dt);
}
// 连接断开时的回调函数
static void connlost(void *context, char *cause)
{
    log_warn("Connection lost,case: %s", cause);
}
// 收到消息时的回调函数
// 返回1表示消息处理成功，返回0表示消息处理失败
static int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int rc = 0;
    if (recv_cb)
    {
        rc = recv_cb((char*)message->payload) == 0 ? 1 : 0;
    }
    // 释放消息和主题
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return rc;
}

int app_mqtt_init(void)
{
    int rc;
    // 创建MQTT客户端
    if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID,
                                MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS)
    {
        log_error("Failed to create client, return code %d", rc);
        return -1;
    }
    // 设置回调函数
    if ((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS)
    {
        log_error("Failed to set callbacks, return code %d", rc);
        MQTTClient_destroy(&client);
        return -1;
    }
    // 连接服务器
    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        log_error("Failed to connect, return code %d", rc);
        MQTTClient_destroy(&client);
        return -1;
    }
    // 订阅主题
    if ((rc = MQTTClient_subscribe(client, TOPIC_PULL, QOS)) != MQTTCLIENT_SUCCESS)
    {
        log_error("Failed to subscribe, return code %d", rc);
        MQTTClient_disconnect(client, TIMEOUT);
        MQTTClient_destroy(&client);
        return -1;
    }
    return 0;
}
void app_mqtt_close(void)
{
    // 取消订阅主题
    MQTTClient_unsubscribe(client, TOPIC_PULL);
    MQTTClient_disconnect(client, TIMEOUT);
    MQTTClient_destroy(&client);
}

int app_mqtt_send(char *json)
{
    pubmsg.payload = json;
    pubmsg.payloadlen = strlen(json);
    if ((MQTTClient_publishMessage(client, TOPIC_PUSH, &pubmsg, NULL)) != MQTTCLIENT_SUCCESS)
    {
        log_error("Failed to publish message");
        return -1;
    }
    return 0;
}

void app_mqtt_registerRecvCallback(int (*callback)(char *json))
{
    recv_cb = callback;
}
